#include "apue.h"
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <wait.h>

void list_dir_files(DIR *);

int main() {
    int fd, exec_flag;
    char fd_str[10];
    DIR *dir;
    pid_t pid;

    if ((fd= open("/", O_RDONLY)) < 0)
        err_sys("oepn error");

    if ((dir= fdopendir(fd)) == NULL)
        err_sys("opendir error");

    if ((exec_flag= fcntl(fd, F_GETFD, FD_CLOEXEC)) < 0) 
        err_sys("fcntl error");

    printf("dir fd flag FD_CLOEXEC is %s\n", exec_flag > 0 ? "on" : "off");

    printf("print dir in parent(fd is %d):\n", fd);
    list_dir_files(dir);

    if ((pid= fork()) < 0) 
        err_sys("fork error");
    else if (pid == 0) {
        printf("execl to print dir at fd %d in child\n", fd);
        sprintf(fd_str, "%d", fd);
        // execlp("ls", "ls", NULL);
        if (execl("/home/guopeng/adv_unix_program/practice_8.7.child", "practice_8.7.child", fd_str, NULL) < 0)
            err_sys("execl error");
        _exit(1);
    }

    if (waitpid(pid, NULL, 0) < 0) 
        err_sys("waitpid error");

    return(0);
}

void list_dir_files(DIR * dir) {
    struct dirent * ent;
    rewinddir(dir);

    errno=0;
    while ((ent= readdir(dir)) != NULL) {
        if (errno != 0)
            err_sys("readdir error");

        if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
            continue;

        printf("%ld %s\n",ent->d_ino, ent->d_name);
    } 
}

